package com.xiayuxuanmin.websocket;

import net.sf.json.JSONObject;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author xiayuxuanmin
 * 与servlet的区别:
 * servlet是单例对象,但是webSocket是多例对象,因为它需要实时连接,需要知道每个连接是谁
 * @Date 2019/8/11
 * @Description
 */
@ServerEndpoint("/websocket/{name}")
public class WebSocket {
    private String name;//用于记录当前websocket是谁
    private Session session;//连接,用于记录当前连接

    private static Map<String,WebSocket> allClient = new HashMap<>();//用静态map来存储所有连接者的websocket

    /**
     * 开启连接
     * @param name 代表地址参数中的name,用来区分连接是谁
     * @param session 当前连接的连接
     */
    @OnOpen//当建立连接时触发
    public void onOpen(@PathParam("name") String name, Session session){
        this.name = name;
        this.session = session;
        System.out.println(name+"连接连接了");
        allClient.put(name,this);
    }

    /**
     * 用于接收客户端发来的消息,这个地方应根据实际需求,来决定到底该怎么写
     * 比如两个人聊天,应该是这里接收到消息之后,看看是发送给谁的,然后转发给另外一个人
     * 如何判断另外的一个接收者是谁:to:zhangsan,message:neirong,data:2019-01-01
     * @param session
     * @param message
     */
    @OnMessage//当服务器接收到消息时触发
    public void onMessage(Session session,String message){
        //首先,解析发送过过来的内容,找到目标接收者
        JSONObject jsonObject = JSONObject.fromObject(message);//将字符串转化为Object对象
        String to = jsonObject.getString("toUser");//找到接收者,页面发送请求过过来的时候,就要携带该参数
        String toMessage = jsonObject.getString("toMessage");;//发送的内容是什么
        //根据目标接收者,来获取目标对应的session连接
        WebSocket webSocket = allClient.get(to);
        //通过session发送消息
        if (webSocket != null) {
            Session toSession = webSocket.getSession();
            if (toSession.isOpen()) {//如果是处于连接状态
                toSession.getAsyncRemote().sendText(toMessage);//找到连接的另外一端,然后发送消息
            }
        }else{
            //正常来说要缓存这个消息,这里就直接给发送者返回一条,对方不在线
            session.getAsyncRemote().sendText("对方不想搭理你,并向你抛出了一个NotOnLineException");
        }
    }

    @OnError//当出现异常时触发
    public void onError(Session session,Throwable e){
        if (session != null && session.isOpen()) {
            try {
                session.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        allClient.remove(name);
    }

    @OnClose//当连接关闭的时候触发
    public void onClose(Session session){
        allClient.remove(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public static Map<String, WebSocket> getAllClient() {
        return allClient;
    }

    public static void setAllClient(Map<String, WebSocket> allClient) {
        WebSocket.allClient = allClient;
    }
}

